"""
配置管理器
负责加载和管理系统配置
"""

import os
import yaml
from typing import Any, Dict, Optional
from pathlib import Path
from dotenv import load_dotenv


class ConfigManager:
    """配置管理器"""

    def __init__(self, config_path: str = None):
        """
        初始化配置管理器
        
        Args:
            config_path: 配置文件路径,默认为 config/config.yaml
        """
        if config_path is None:
            # 获取项目根目录
            self.root_dir = Path(__file__).parent.parent.parent
            config_path = self.root_dir / "config" / "config.yaml"
        else:
            self.root_dir = Path(config_path).parent.parent
            config_path = Path(config_path)

        self.config_path = config_path
        self.config: Dict[str, Any] = {}
        self._load_config()
        self._load_env()

    def _load_config(self):
        """加载YAML配置文件"""
        try:
            with open(self.config_path, 'r', encoding='utf-8') as f:
                self.config = yaml.safe_load(f)
            print(f"✓ 配置文件加载成功: {self.config_path}")
        except FileNotFoundError:
            raise FileNotFoundError(f"配置文件不存在: {self.config_path}")
        except yaml.YAMLError as e:
            raise ValueError(f"配置文件格式错误: {e}")

    def _load_env(self):
        """加载环境变量(.env文件)"""
        env_path = self.root_dir / "config" / ".env"
        if env_path.exists():
            load_dotenv(env_path)
            print(f"✓ 环境变量加载成功: {env_path}")

            # 从环境变量覆盖敏感配置
            if os.getenv("BILIBILI_ROOM_ID"):
                self.config["bilibili"]["room_id"] = int(os.getenv("BILIBILI_ROOM_ID"))

            if os.getenv("DEEPSEEK_API_KEY"):
                self.config["deepseek"]["api_key"] = os.getenv("DEEPSEEK_API_KEY")

            if os.getenv("BAIDU_TTS_APP_ID"):
                self.config["baidu_tts"]["app_id"] = os.getenv("BAIDU_TTS_APP_ID")
            if os.getenv("BAIDU_TTS_API_KEY"):
                self.config["baidu_tts"]["api_key"] = os.getenv("BAIDU_TTS_API_KEY")
            if os.getenv("BAIDU_TTS_SECRET_KEY"):
                self.config["baidu_tts"]["secret_key"] = os.getenv("BAIDU_TTS_SECRET_KEY")
        else:
            print(f"⚠ 未找到.env文件: {env_path}")

    def get(self, key: str, default: Any = None) -> Any:
        """
        获取配置项(支持点号分隔的嵌套键)
        
        Args:
            key: 配置键,如 'bilibili.room_id'
            default: 默认值
            
        Returns:
            配置值
        """
        keys = key.split('.')
        value = self.config

        for k in keys:
            if isinstance(value, dict):
                value = value.get(k)
                if value is None:
                    return default
            else:
                return default

        return value

    def set(self, key: str, value: Any):
        """
        设置配置项
        
        Args:
            key: 配置键,如 'bilibili.room_id'
            value: 配置值
        """
        keys = key.split('.')
        config = self.config

        for k in keys[:-1]:
            if k not in config:
                config[k] = {}
            config = config[k]

        config[keys[-1]] = value

    def validate(self) -> bool:
        """
        验证必填配置项
        
        Returns:
            是否验证通过
        """
        required_fields = [
            ("bilibili.room_id", "B站直播间ID"),
            ("deepseek.api_key", "DeepSeek API密钥"),
            ("baidu_tts.app_id", "百度TTS应用ID"),
            ("baidu_tts.api_key", "百度TTS API密钥"),
            ("baidu_tts.secret_key", "百度TTS Secret密钥"),
        ]

        missing_fields = []
        for field, description in required_fields:
            value = self.get(field)
            if not value or (isinstance(value, (str, int)) and str(value) in ["", "0", "your_", "填写"]):
                missing_fields.append(f"{description} ({field})")

        if missing_fields:
            print("❌ 配置验证失败,缺少以下必填项:")
            for field in missing_fields:
                print(f"  - {field}")
            return False

        print("✓ 配置验证通过")
        return True

    def get_system_prompt(self) -> str:
        """获取虚拟主播的系统提示词"""
        return self.get("character.system_prompt", "你是一个AI虚拟主播。")

    def get_bilibili_config(self) -> Dict[str, Any]:
        """获取B站相关配置"""
        return self.get("bilibili", {})

    def get_deepseek_config(self) -> Dict[str, Any]:
        """获取DeepSeek相关配置"""
        return self.get("deepseek", {})

    def get_tts_config(self) -> Dict[str, Any]:
        """获取TTS相关配置"""
        # 获取TTS引擎类型
        engine = self.get("tts.engine", "baidu_tts")
        
        if engine == "chattts":
            return self.get("tts.chattts", {})
        elif engine == "fish_audio":
            return self.get("tts.fish_audio", {})
        elif engine == "minimax":
            return self.get("tts.minimax", {})
        elif engine == "volcengine":
            return self.get("tts.volcengine", {})
        else:
            # 默认使用百度TTS
            return self.get("baidu_tts", {})
    
    def get_tts_engine_type(self) -> str:
        """获取TTS引擎类型"""
        return self.get("tts.engine", "baidu_tts")

    def get_live2d_config(self) -> Dict[str, Any]:
        """获取Live2D相关配置"""
        return self.get("live2d", {})

    def get_system_config(self) -> Dict[str, Any]:
        """获取系统运行配置"""
        return self.get("system", {})

    def save(self):
        """保存配置到文件"""
        try:
            with open(self.config_path, 'w', encoding='utf-8') as f:
                yaml.dump(self.config, f, allow_unicode=True, default_flow_style=False)
            print(f"✓ 配置已保存: {self.config_path}")
        except Exception as e:
            print(f"❌ 保存配置失败: {e}")


# 创建全局配置实例
_config_instance: Optional[ConfigManager] = None


def get_config(config_path: str = None) -> ConfigManager:
    """
    获取配置管理器单例
    
    Args:
        config_path: 配置文件路径(仅首次调用时有效)
        
    Returns:
        ConfigManager实例
    """
    global _config_instance
    if _config_instance is None:
        _config_instance = ConfigManager(config_path)
    return _config_instance
